package main

import (
	"fmt"
	"net"
	"os"
	"os/signal"
	"syscall"
	"trade_rpc/global"
	"trade_rpc/handler"
	"trade_rpc/initialize"
	"trade_rpc/util/otgrpc"
	"trade_rpc/util/register/consul"

	pb "trade_rpc/proto"

	"github.com/google/uuid"
	"github.com/opentracing/opentracing-go"
	"github.com/uber/jaeger-client-go"
	jaegercfg "github.com/uber/jaeger-client-go/config"
	jaegerlog "github.com/uber/jaeger-client-go/log"
	"github.com/uber/jaeger-lib/metrics"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/health"
	"google.golang.org/grpc/health/grpc_health_v1"
)

func main() {

	// mode 开发模式,local, dev,test,prod
	mode := os.Getenv("BUILD_ENV")

	if mode == "" {
		mode = "local"
	}

	// 获取是否是debug模式
	isDebug := initialize.IsDebug(mode)

	// 初始化logger
	initialize.InitLogger(isDebug)

	// 初始化配置文件
	initialize.InitConfig(mode)

	// 初始化数据库
	initialize.InitDatabase(isDebug)

	// 初始化es
	// initialize.InitElasticClient(isDebug)

	// 初始化 trade manager
	initialize.InitTradeManager(mode)

	// 初始化jaeger
	cfg := jaegercfg.Configuration{
		Sampler: &jaegercfg.SamplerConfig{
			Type:  jaeger.SamplerTypeConst,
			Param: 1,
		}, // 采样
		Reporter: &jaegercfg.ReporterConfig{
			LogSpans:           true,
			LocalAgentHostPort: fmt.Sprintf("%s:%d", global.ServerConfig.Jaeger.Host, global.ServerConfig.Jaeger.Port),
		},
		ServiceName: global.ServerConfig.Jaeger.Name,
	}

	jLogger := jaegerlog.StdLogger
	jMetricsFactory := metrics.NullFactory
	tracer, closer, err := cfg.NewTracer(
		jaegercfg.Logger(jLogger),
		jaegercfg.Metrics(jMetricsFactory),
	)
	if err != nil {
		panic(err)
	}
	opentracing.SetGlobalTracer(tracer)
	server := grpc.NewServer(grpc.UnaryInterceptor(otgrpc.OpenTracingServerInterceptor(tracer)))

	pb.RegisterTradeRecordServer(server, &handler.TradeServer{})

	// 监听端口
	var port = global.ServerConfig.Port
	lis, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port))
	if err != nil {
		panic(err)
	}

	// 注册健康检查
	grpc_health_v1.RegisterHealthServer(server, health.NewServer())

	// 服务注册
	registry := consul.NewRegistry(global.ServerConfig.Consul.Host, global.ServerConfig.Consul.Port)
	var serviceId = uuid.Must(uuid.NewUUID()).String()
	err = registry.Register(global.ServerConfig.Host, port, global.ServerConfig.Name, global.ServerConfig.Tags, serviceId)
	if err != nil {
		zap.L().Panic("consul client error", zap.Error(err))
	}

	go func() {
		if err = server.Serve(lis); err != nil {
			panic(err)
		}
	}()

	// 优雅退出
	// kill -9 是捕捉不到的
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	closer.Close()
	zap.L().Info("Shutdown Server.")
	zap.L().Info("注册中心主动注销服务")

	// 注销服务
	err = registry.DeRegister(serviceId)
	if err != nil {
		zap.L().Error("注销consul失败", zap.Error(err))
	}

	// 同步logger信息
	zap.L().Sync()
}
